﻿using System;
using System.Text.RegularExpressions;

namespace CardPlay.Model.GameModel
{
    public struct PartLocation : IEquatable<PartLocation>
    {
        public PartLocation(string path) : this(path, -1)
        {
        }

        public PartLocation(string path, int index)
        {
            Path = path;
            Index = index;
        }
        
        public string Path;
        public int Index;
        
        public bool IsUndefined
        {
            get { return String.IsNullOrEmpty(Path);  }
        }

        public PartLocation Parent
        {
            get
            {
                var index = Path.LastIndexOf('.');
                return new PartLocation(index == -1 ? String.Empty : Path.Substring(0, index));
            }
        }

        public PartLocation PreviousLocation
        {
            get { return new PartLocation(Path, Index - 1); }
        }

        public PartLocation NextLocation
        {
            get { return new PartLocation(Path, Index + 1); }
        }

        public int Id
        {
            get
            {
                var id = 0;
                var index = Path.LastIndexOf('.');
                
                if (index != -1 && index + 1 < Path.Length)
                {
                    try
                    {
                        id = Int32.Parse(Path.Substring(index + 1));
                    }
                    catch (FormatException)
                    {
                    }
                }
                
                return id;
            }
        }
        
        public bool Matches(string pattern)
        {
            return Regex.IsMatch(Path, pattern);
        }

        public override string ToString()
        {
            return String.Format("Location({0},{1})", Path, Index);
        }
        
        public static PartLocation Empty
        {
            get { return new PartLocation(); }
        }
        
        public bool Equals(PartLocation other)
        {
            return Equals(other.Path, Path) && other.Index == Index;
        }

        public override bool Equals(object obj)
        {
            return !ReferenceEquals(null, obj) && (obj is PartLocation && Equals((PartLocation) obj));
        }

        public override int GetHashCode()
        {
            unchecked
            {
                return ((Path != null ? Path.GetHashCode() : 0) * 397) ^ Index;
            }
        }

        public static bool operator ==(PartLocation a, PartLocation b)
        {
            return a.Equals(b);
        }

        public static bool operator !=(PartLocation a, PartLocation b)
        {
            return !a.Equals(b);
        }
    }
}
